<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        svg {
            flex-shrink: 0;
            min-width: 600px;
        }

        #me {
            opacity: 0
        }
    </style>
</head>

<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.1/gsap.min.js"></script>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 211.73 188.36">
        <defs>
            <clipPath id="clip-path">
                <path
                    d="M39 153.73s31.57 19.71 77.26 15.21 90.18-37.23 90.36-72.33-8.82-80.28-33.59-86.29C136.84-6.57 114.13-5.82 88-2.82S34.73 11.45 16.71 48.24C-1.5 66.64-4.88 125.2 39 153.73z"
                    fill="none" />
            </clipPath>
            <clipPath id="clip-path-2">
                <path id="mouth-clip"
                    d="M98.93 112.17c2.78 1.59 7.5 1.67 9.31 1.17 2.3-.62 5.68-1.48 5.59-5.35-.06-3.22-2.93-3.73-4.72-3.41-5 .91-5.46-.2-8.93-.39-2.61-.14-4.28 1.23-4.43 3.8-.12 2.13 1.91 3.46 3.18 4.18z"
                    fill="none" />
            </clipPath>
            <path opacity="0" id="yawn-clip"
                d="M105.4 117.65c6 0 7.67-1.66 7.3-5.83s-2.64-10.27-7.86-10.27-6.48 6.37-6.85 9.92 1.38 6.18 7.41 6.18z"
                fill="#fff" />
        </defs>

        <path id="bg"
            d="M39 153.73s31.57 19.71 77.26 15.21 90.18-37.23 90.36-72.33-10.51-57-35.28-63-50.22 17-76.31 20-60.12-15.88-78.32 2.51S-4.88 125.2 39 153.73z"
            fill="#6fdcbf" />
        <g clip-path="url(#clip-path)">
            <g id="me" data-name="me">
                <g id="body">
                    <path id="shadow" class="shadow"
                        d="M129.86 48.47s6.76 4.52 10 11.1 7 26.74 11.71 36.64 9.06 20.7 9.91 24.3 1.57 4.58-2.52 9.39-14.63 11-14.63 11l-11.47 6.25s14.87 8.9 17.68 17.78a61.07 61.07 0 014.34 17.28l-21.39 4.18-20.29-30.85-13-10.22-9.89-72.1z"
                        opacity=".09" />
                    <path id="shadow-2" class="shadow" data-name="shadow"
                        d="M69.44 54a22.91 22.91 0 00-10.53 9.56c-4.39 7.32-4.1 28.4-7.61 38.36s-10.54 17.46-9.37 27.42 2.64 11.42 2.64 11.42a71.6 71.6 0 0114.93 1.75c7 1.76 18.42 5.1 18.42 5.1s-14.32 11.1-16.08 19.89a58.63 58.63 0 00-2.34 17l20.89 1.76 16.19-31.62L108 143.51l1.91-70z"
                        opacity=".09" />
                    <path id="hair-back" class="hair"
                        d="M127.11 47.07c2.53 1.26 10.63 1.45 15.32 19.12 2.74 19.22 3.61 24.35 4.46 28.58s1.14 10.83 6 19.75.81 13.68.81 13.68l-7.27 6.61s3.29-11.81-2.51-16.93c0 0 1.92 13.11 0 15.85s-8.33 6.46-8.33 6.46-2.37-4.23-4.83-9 2.65 10.25.08 11.29-17.93 5.84-29.16 3.6-20.51-4.66-22.85-5.4c0 0 2.62-1.28.74-7.12s-.92-7.09-1.45-6.52-2 2.77-1 7a6.88 6.88 0 01-1.83 6.7s-6.78-4.34-12.17-4.86a49.5 49.5 0 01-9-1.66s-4.73-10.67-.38-22 7-12.59 7.33-26.81S64 51 81.15 41.34s35.71-3.4 45.96 5.73z"
                        fill="#cec6a5" fill-rule="evenodd" />
                    <path id="neck"
                        d="M114.26 143.16v-14a9.22 9.22 0 10-18.43 0v14c-15.27 2.84-24.74 15.08-24.74 27.33H139c0-12.24-9.5-24.49-24.74-27.33z"
                        fill="#ede3d1" />
                    <path id="top"
                        d="M105.61 167c-30.17 0-25.36-40-25.36 15.84h25.35l25-2.14c-.05-55.79 5.17-13.7-24.99-13.7z"
                        fill="#fff" stroke="#404040" stroke-miterlimit="10" stroke-width=".5" />
                    <path id="shoulder" d="M95.82 142.87c-16 1.84-29.37 19.5-29.37 40h29.37z" fill="#404040" />
                    <path id="shoulder-2" data-name="shoulder" d="M114.23 142.67c15.76 1.85 29 19.6 29 40.2h-29z"
                        fill="#404040" />
                </g>

                <g id="head">
                    <path id="shadow-3" data-name="shadow" d="M95.82 122.36h18.41v14.31s-10.5 5.54-18.41 0z"
                        fill="#efceb9" />
                    <g id="ear-left" class="ear">
                        <path
                            d="M63.52 105.14A8.21 8.21 0 0072 113.2a8.36 8.36 0 008.51-8.1A8.21 8.21 0 0072 97a8.36 8.36 0 00-8.48 8.14z"
                            fill="#ede3d1" />
                        <path
                            d="M68.54 104.48a17 17 0 014.14.41c1.07.31 1.94 1 3 1.31a.39.39 0 00.43-.57c-1.15-2.38-5.49-1.86-7.58-1.67a.26.26 0 000 .52z"
                            fill="#b5aa9a" />
                    </g>
                    <g id="ear-right" class="ear">
                        <path
                            d="M144.37 105.24a8.2 8.2 0 01-8.37 8.06 8.35 8.35 0 01-8.51-8.1 8.21 8.21 0 018.42-8.06 8.35 8.35 0 018.46 8.1z"
                            fill="#ede3d1" />
                        <path
                            d="M139.6 104c-2.1-.19-6.43-.72-7.59 1.67a.39.39 0 00.44.57c1.07-.26 1.92-1 3-1.31a17.51 17.51 0 014.15-.41.26.26 0 000-.52z"
                            fill="#b5aa9a" />
                    </g>
                    <g id="face">
                        <rect x="73.99" y="48.26" width="61.54" height="80.49" rx="26.08"
                            transform="rotate(180 104.76 88.5)" fill="#ede3d1" />
                        <g id="inner-face">
                            <path id="eyebrow-right" d="M120.73 79a9 9 0 00-4-1.22 9.8 9.8 0 00-4.19.87" fill="none"
                                stroke="#b5aa9a" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.04" />
                            <path id="eyebrow-left" d="M97.12 79.41a9.53 9.53 0 00-4-1.11 10.58 10.58 0 00-4.2.76"
                                fill="none" stroke="#b5aa9a" stroke-linecap="round" stroke-linejoin="round"
                                stroke-width="1.04" />

                            <g clip-path="url(#clip-path-2)">
                                <g id="mouth" opacity="0">
                                    <ellipse cx="104.95" cy="106.66" rx="9.92" ry="9.48" fill="#2b343b" />
                                    <path id="tongue"
                                        d="M111.44 112.27a14.53 14.53 0 01-13.29-.37s1.52-3.48 6.56-3.35 6.73 3.72 6.73 3.72z"
                                        fill="#ffaa96" />
                                </g>
                            </g>
                            <path id="mouth-2" data-name="mouth" d="M97 107.52s7.06 4.62 14 1.59" fill="none"
                                stroke="#b5aa9a" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.04" />
                            <path id="eye-left" class="eye" opacity="0"
                                d="M89.48 87.37c-.07 2.08 1.25 3.8 2.94 3.85s3.1-1.59 3.16-3.67-1.25-3.8-2.94-3.85-3.1 1.59-3.16 3.67z"
                                fill="#2b343b" />
                            <path id="eye-right" class="eye" opacity="0"
                                d="M113.67 87.37c-.07 2.08 1.25 3.8 2.94 3.85s3.1-1.59 3.16-3.67-1.25-3.8-2.94-3.85-3.1 1.59-3.16 3.67z"
                                fill="#2b343b" />
                            <path id="eye-right-2" class="eye" data-name="eye-right"
                                d="M114.11 88a5.72 5.72 0 002.48.72 6.46 6.46 0 002.59-.45" fill="none" stroke="#282828"
                                stroke-linecap="round" stroke-linejoin="round" stroke-width="1.04" />
                            <path id="eye-left-2" class="eye" data-name="eye-left"
                                d="M89.85 88a5.77 5.77 0 002.56.3 6.48 6.48 0 002.49-.87" fill="none" stroke="#282828"
                                stroke-linecap="round" stroke-linejoin="round" stroke-width="1.04" />
                            <path id="nose" d="M102.39 98.13s3.09 1.55 5.78 0" fill="none" stroke="#e0d5c1"
                                stroke-linecap="round" stroke-linejoin="round" />
                            <path id="glasses"
                                d="M133.54 81.76c-4.7-1.42-15.29-2.42-19.83-.45-5.82 2.17-3.18 1.57-8.55 1.17-5.36.4-2.74 1-8.55-1.18-7.3-2.55-15.58-.24-22.25.72v2.75c2.46.24 1.26 6.78 3.06 10.32 2.13 7.23 12.69 9.55 18.19 5.49 3.9-2 7.08-10.32 7.21-12.86 0-1.64 4.15-2.57 4.61.24.11 2.53 3.42 10.69 7.28 12.62 5.5 4 16 1.74 18.17-5.49 1.8-3.54 1.69-9.92 2.88-10.32s.74-2.67 0-2.75-1.02-.1-2.22-.26zM97.25 97.49C90.94 104.81 79 101.2 78 92.3c-.7-2.62-1-7.3 1.27-9.12s6.88-1.87 9.23-2c11.14-.26 16.62 5.6 8.75 16.31zm35.12-5.19c-3.71 17.2-27.26 7.42-22.09-7.36 1.87-3.11 9.09-3.84 11.55-3.73 8.07-.04 12.7 1.79 10.54 11.09z"
                                fill="#c6c6c6" opacity=".48" />
                            <path id="blush-left" class="eye"
                                d="M89.9 98.17a2.66 2.66 0 01-1.55-.93 3.73 3.73 0 01-.76-3.12 3 3 0 011-1.56 2 2 0 011.4-.42 3 3 0 012.5 2.72.76.76 0 010 .21 3.19 3.19 0 01.11.91 2.1 2.1 0 01-1.77 2.21 2.07 2.07 0 01-.93-.02zM89.34 96v-.05s-.04.05 0 .05z"
                                fill="#efceb9" fill-rule="evenodd" />
                            <path id="blush-right" class="eye"
                                d="M118.93 98.19a2.09 2.09 0 01-1.77-2.19 3.58 3.58 0 01.1-.91v-.21a3 3 0 012.51-2.72 2 2 0 011.4.42 3 3 0 011 1.56 3.73 3.73 0 01-.76 3.12 2.66 2.66 0 01-1.55.93 2.08 2.08 0 01-.93 0zm1.53-2.2v.05c0 .05.05-.04 0-.04z"
                                fill="#efceb9" fill-rule="evenodd" />
                        </g>
                        <path id="hair-front"
                            d="M116.77,52.8s7.6,10.26,13.35,14.57c4.35,6.36,4.87,17.81,7,17.81s.77-9.86.77-14.55-1.85-9.48-5-14.74-8.27-9.29-15.9-12a40.17,40.17,0,0,0-22.45-1.69c-7.81,1.62-13,3.55-18.23,8.31S68,59.18,66.92,69.23s5.29,52.84,6.71,53.09,0-43.61,3.76-48.31C90.57,57.72,102,64.62,116.77,52.8Z"
                            fill="#cec6a5" />

                    </g>
                </g>
            </g>
        </g>
    </svg>

    <script>
        window.ScrubGSAPTimeline = (tl) => {
            let mainTl = new TimelineLite();
            if (Object.prototype.toString.call(tl) === '[object Array]') {
                let i = tl.length;
                while (--i > -1) {
                    mainTl.add(tl[i], 0);
                }

            } else {
                mainTl = tl;
            }
            const Scrubber = (_tl) => {

                let mouseMove = (e) => {
                    box.innerHTML = parseFloat(_tl.time()).toFixed(2);
                    _tl.pause();
                    _tl.progress(e.clientX / (window.innerWidth)); // * tl.duration();
                    mouseX = e.clientX, mouseY = e.clientY;

                    TweenLite.set(box, {
                        x: (mouseX >= (window.innerWidth - 48)) ? mouseX - 48 : mouseX,
                        y: (mouseY <= 20) ? mouseY + 20 : mouseY - 20
                    })
                },
                    mouseOver = (e) => {
                        _tl.pause();
                        _tl.play(0);
                        TweenLite.set(box, {
                            autoAlpha: 1
                        })
                    },
                    mouseOut = (e) => {
                        _tl.play(e.clientX / (window.innerWidth) * _tl.duration());
                        TweenLite.set(box, {
                            autoAlpha: 0
                        })
                    },
                    box = document.createElement('div'),
                    mouseX, mouseY, gGreen = '#53A018',
                    cssText = "position:fixed;border-radius:4px;font-size:14px;padding:5px;user-select:none;pointer-events:none;text-align:center;color:#53A018;top:0;left:0;font-family:Helvetica, Arial, sans-serif;background-color:#262626;line-height:1 !important;z-index:99999999"
                box.style.cssText = cssText;

                document.body.appendChild(box);
                document.body.onmousemove = mouseMove;
                document.body.onmouseover = mouseOver;
                document.body.onmouseout = mouseOut;
                document.body.ondblclick = (e) => {
                    if (!document.body.onmousemove) {
                        TweenLite.to(box, 0.2, {
                            color: gGreen
                        })
                        document.body.onmousemove = mouseMove;
                        document.body.onmouseover = mouseOver;
                        document.body.onmouseout = mouseOut;
                        return;
                    }

                    TweenLite.to(box, 0.2, {
                        color: '#A31632'
                    })
                    document.body.onmousemove = null;
                    document.body.onmouseover = null;
                    document.body.onmouseout = null;
                    _tl.pause();

                }


            }

            Scrubber(mainTl);
        }

        const meTl = gsap.timeline({
            onComplete: addMouseEvent,
            delay: 2,
        });

        gsap.set('#bg', { transformOrigin: '50% 50%' });
        gsap.set('#ear-right', { transformOrigin: '0% 50%' });
        gsap.set('#ear-left', { transformOrigin: '100% 50%' });
        gsap.set('#me', { opacity: 1 });

        meTl
            .from('#me', { duration: 1, yPercent: 100, ease: Elastic.easeOut.config(0.5, 0.4) })
            .from(
                ['#head', '.hair', '.shadow'],
                { duration: 0.9, yPercent: 20, ease: Elastic.easeOut.config(0.58, 0.25) },
                0.1
            )
            .from(
                '#ear-right',
                { duration: 1, rotate: 40, yPercent: 10, ease: Elastic.easeOut.config(0.5, 0.2) },
                0.2
            )
            .from(
                '#ear-left',
                { duration: 1, rotate: -40, yPercent: 10, ease: Elastic.easeOut.config(0.5, 0.2) },
                0.2
            )
            .to(
                '#glasses',
                {
                    duration: 1,
                    keyframes: [{ yPercent: -10 }, { yPercent: -0 }],
                    ease: Elastic.easeOut.config(0.5, 0.2)
                },
                0.25
            )
            .from(
                ['#eyebrow-right', '#eyebrow-left'],
                { duration: 1, yPercent: 300, ease: Elastic.easeOut.config(0.5, 0.2) },
                0.2
            )
            .to(['#eye-right', '#eye-left'], { duration: 0.01, opacity: 1 }, 0.35)
            .to(['#eye-right-2', '#eye-left-2'], { duration: 0.01, opacity: 0 }, 0.35);
        // end animation


        // mouse coords

        let xPosition;
        let yPosition;

        let xPercent;
        let yPercent;

        let height;
        let width;

        function percentage(partialValue, totalValue) {
            return ((100 * partialValue) / totalValue).toFixed(2) * 1;
        }

        function updateWindowSize() {
            height = window.innerHeight;
            width = window.innerWidth;
        }
        updateWindowSize();

        function updateScreenCoords(event) {
            if (event) {
                xPosition = event.clientX;
                yPosition = event.clientY;
            }
        }

        let storedXPosition = 0;
        let storedYPosition = 0;

        function animateFace() {
            if (xPosition) {
                // important, only recalculating if the value changes
                if (storedXPosition != xPosition && storedYPosition != yPosition) {
                    console.log(xPosition, yPosition);

                    xPercent = percentage(xPosition, width) - 50;
                    yPercent = percentage(yPosition, height) - 20;

                    yPercentLow = percentage(yPosition, height) - 80;
                    yPercentHigh = percentage(yPosition, width) - 50;

                    gsap.to('#face', { yPercent: yPercentLow / 30, xPercent: xPercent / 30 });
                    gsap.to('.eye', { yPercent: yPercent / 3, xPercent: xPercent / 2 });
                    gsap.to('#inner-face', { yPercent: yPercentHigh / 6, xPercent: xPercent / 8 });
                    gsap.to('#hair-front', { yPercent: yPercent / 15, xPercent: xPercent / 22 });
                    gsap.to(['#hair-back', '.shadow'], {
                        yPercent: (yPercentLow / 20) * -1,
                        xPercent: (xPercent / 20) * -1
                    });
                    gsap.to('.ear', {
                        yPercent: (yPercentHigh / 1.5) * -1,
                        xPercent: (xPercent / 10) * -1
                    });
                    gsap.to(['#eyebrow-left', '#eyebrow-right'], { yPercent: yPercentHigh * 2.5 });

                    storedXPosition = xPosition;
                    storedYPosition = yPosition;
                }
            }
        }

        const blink = gsap.timeline({ repeat: -1, repeatDelay: 5, paused: true });

        blink.to(['#eye-right', '#eye-left'], { duration: 0.01, opacity: 0 }, 0);
        blink.to(['#eye-right-2', '#eye-left-2'], { duration: 0.01, opacity: 1 }, 0);
        blink.to(['#eye-right', '#eye-left'], { duration: 0.01, opacity: 1 }, 0.15);
        blink.to(['#eye-right-2', '#eye-left-2'], { duration: 0.01, opacity: 0 }, 0.15);

        // function being called at the end of main timeline
        function addMouseEvent() {
            document.addEventListener('mousemove', updateScreenCoords);

            // gsap's RAF, falls back to set timeout
            gsap.ticker.add(animateFace);

            blink.play();
        }

        window.addEventListener('resize', updateWindowSize);
    </script>
</body>

</html>